from asgiref.sync import sync_to_async
from cy_query.db import OperationalError, connections


def execute_dynamic_query(instance, query, params=None):
    """
    执行指定数据库配置的 SQL 查询。
    参数：
    - database_config: dict，数据库配置，例如：
        {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'your_db_name',
            'USER': 'your_user',
            'PASSWORD': 'your_password',
            'HOST': 'your_host',
            'PORT': 'your_port',
        }
    - query: str，SQL 查询语句。
    - params: tuple，查询参数，用于安全传参（防止SQL注入）。
    """
    # 配置动态数据库连接
    settings_dict = {
        'ENGINE': instance.db.engine,
        'NAME': instance.db.database,
        'USER': instance.db.user,
        'PASSWORD': instance.db.password,
        'HOST': instance.db.host,
        'PORT': instance.db.port,
        'OPTIONS': {

        },
        'TIME_ZONE': None,
        'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None},
        'ATOMIC_REQUESTS': False,
        'AUTOCOMMIT': True,
        'CONN_MAX_AGE': 0,
        'CONN_HEALTH_CHECKS': False
    }
    if instance.db.options and isinstance(instance.db.options, dict):
        settings_dict['OPTIONS'] = instance.db.options
    alias = str(settings_dict)

    connections.databases[alias] = settings_dict
    try:
        # 获取数据库连接
        with connections[alias].cursor() as cursor:
            # 执行查询
            cursor.execute(query, params)
            # 若查询返回数据，获取数据
            if query.strip().lower().startswith('select'):
                columns = [col[0] for col in cursor.description]
                # 将结果转换为列表字典
                result = [dict(zip(columns, row)) for row in cursor.fetchall()]
            else:
                # 对于非 SELECT 查询，返回影响的行数
                result = cursor.rowcount
    except OperationalError as e:
        raise OperationalError(f"数据库连接出错：{e}")
    return result


async def aexecute_dynamic_query(instance, query, params=None):
    return await sync_to_async(execute_dynamic_query)(instance, query, params=None)
